#include "preHeader.h"
#include "Session/PlayerPacketHandler.h"
#include "Map/MapInstance.h"
#include "Map/StoryHook.h"

int PlayerPacketHandler::HandleCharacterTeleportFailed(Player *pPlayer, INetPacket &pck)
{
	int32 errCode;
	pck >> errCode;
	pPlayer->SendError((GErrorCode)errCode);
	pPlayer->TeleportEnd(false);
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleCharacterLeaveMap(Player *pPlayer, INetPacket &pck)
{
	InstGUID instGuid;
	vector3f1f tgtPos;
	pck >> instGuid >> tgtPos;
	pPlayer->GetMapInstance()->
		TryPlayerLeaveMap(false, pPlayer->GetGuid(), instGuid, tgtPos);
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleTryGuildCreate(Player *pPlayer, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	NetPacket rpcRespPck(GS_RPC_INVOKE_RESP);
	auto errCode = pPlayer->HandleTryGuildCreate();
	rpcRespPck << (int32)errCode;
	pPlayer->RPCReply2Gs(rpcRespPck, info.sn);
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleGuildCreateResp(Player *pPlayer, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	NetPacket rpcRespPck(GS_RPC_INVOKE_RESP);
	auto errCode = pPlayer->HandleGuildCreateResp();
	rpcRespPck << (int32)errCode;
	pPlayer->RPCReply2Gs(rpcRespPck, info.sn);
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleJoinGuildEvent(Player *pPlayer, INetPacket &pck)
{
	uint32 guildId;
	int8 guildTitle;
	std::string_view guildName;
	pck >> guildId >> guildTitle >> guildName;
	pPlayer->SetGuild(guildId, guildTitle, guildName);
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleQuitGuildEvent(Player *pPlayer, INetPacket &pck)
{
	uint32 guildId;
	std::string_view guildName;
	pck >> guildId >> guildName;
	pPlayer->SetGuild(0, 0, emptyStringView);
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleGetChatMessageThing(Player *pPlayer, INetPacket &pck, const RPCActor::RequestMetaInfo &info)
{
	NetPacket rpcRespPck(MS_RPC_INVOKE_RESP);
	while (!pck.IsReadableEmpty()) {
		int8 thingType;
		uint32 thingId;
		pck >> thingType >> thingId;
		rpcRespPck << thingType << thingId;
		auto anchor = rpcRespPck.Placeholder(true);
		if (!pPlayer->GetChatMessageThing(rpcRespPck, thingType, thingId)) {
			rpcRespPck.Put(anchor, false);
		}
	}
	pPlayer->RPCReply2Gs(rpcRespPck, info.sn);
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleObjectInteractive(Player *pPlayer, INetPacket &pck)
{
	ObjGUID targetGuid;
	vector3f selfPos, selfDir;
	pck >> targetGuid >> selfPos >> selfDir;

	pPlayer->SetPosition(selfPos);
	pPlayer->SetDirection(selfDir);

	auto pTarget = pPlayer->GetMapInstance()->GetLocatableObject(targetGuid);
	if (pTarget == NULL) {
		pPlayer->SendError(TargetNotExist);
		return SessionHandleSuccess;
	}

	GErrorCode errCode = InvalidRequest;
	switch (pTarget->GetObjectType()) {
	case TYPE_STATICOBJECT:
		errCode = ((StaticObject*)pTarget)->TryInteractive(pPlayer);
		break;
	}
	if (errCode != CommonSuccess) {
		pPlayer->SendError(errCode);
		return SessionHandleSuccess;
	}

	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandlePlayerRevive(Player *pPlayer, INetPacket &pck)
{
	auto errCode = pPlayer->TryRevive();
	if (errCode != CommonSuccess) {
		pPlayer->SendError(errCode);
	}
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleLocTeleportFinish(Player *pPlayer, INetPacket &pck)
{
	pPlayer->TeleportEnd();
	return SessionHandleSuccess;
}

int PlayerPacketHandler::HandleStartStoryMode(Player *pPlayer, INetPacket &pck)
{
	if (pPlayer->GetMapType() == (u32)MapInfo::Type::Story) {
		((StoryHook*)pPlayer->GetMapInstance()->GetHook())->Play();
	}
	return SessionHandleSuccess;
}
